//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//

/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


using System;
using EffiProz.Core.Lib;
using EffiProz.Core.Errors;
using System.Collections.Generic;
using System.Web;

namespace EffiProz.Core.Persist
{
    internal static class MediumTrustHelper
    {
        private static bool mediumTrust = _RunningMediumTrust();

        private static bool _RunningMediumTrust()
        {
// we only do the full check if compiled with medium_trust_support
// since the check requires loading System.Web.dll in the working set
#if (MEDIUM_TRUST_SUPPORT)
            if (!System.Web.Hosting.HostingEnvironment.IsHosted)
            {
                return false;
            }

            // try demanding for High permission
            try
            {
                new AspNetHostingPermission(AspNetHostingPermissionLevel.High).Demand();
            }
            catch (System.Security.SecurityException)
            {
                // if we are here, the code is running in Medium Trust or lower.
                return true;
            }
#endif
            return false;
        }

        public static bool RunningMediumTrust
        {
            get
            {
                return mediumTrust;
            }
        }
    }
    /**
     * Manages a .properties file for a database.
     *
     * @author fredt@users
     * @version 1.8.0
     * @since 1.7.0
     */


    public class EffiProzDatabaseProperties : EffiProzProperties
    {
        private static string effiproz_method_class_names = "effiproz.method_class_names";

        private static HashSet accessibleCSharpMethodNames = null;


        static EffiProzDatabaseProperties()
        {
#if !SILVERLIGHT && !PLATFORM_COMPACTFRAMEWORK
            try
            {

                // in medium trust accessing GetEnvironmentVariable throws exception
                string prop = MediumTrustHelper.RunningMediumTrust ? null : Environment.GetEnvironmentVariable(effiproz_method_class_names);

                if (prop != null)
                {
                    accessibleCSharpMethodNames = new HashSet();

                    string[] names = prop.Split(";".ToCharArray());

                    foreach (var name in names)
                    {
                        accessibleCSharpMethodNames.add(name);
                    }
                }
            }
            catch (Exception) { }
#endif

            // text table defaults
            textMeta.Add(textdb_allow_full_path,
                         getMeta(textdb_allow_full_path,
                                                SYSTEM_PROPERTY, false));
            textMeta.Add(textdb_quoted,
                         getMeta(textdb_quoted, SQL_PROPERTY,
                                                false));
            textMeta.Add(textdb_all_quoted,
                         getMeta(textdb_all_quoted, SQL_PROPERTY,
                                                false));
            textMeta.Add(textdb_ignore_first,
                         getMeta(textdb_ignore_first, SQL_PROPERTY,
                                                false));
            textMeta.Add(textdb_fs,
                         getMeta(textdb_fs, SQL_PROPERTY, ","));
            textMeta.Add(textdb_vs,
                         getMeta(textdb_vs, SQL_PROPERTY, null));
            textMeta.Add(textdb_lvs,
                         getMeta(textdb_lvs, SQL_PROPERTY, null));
            textMeta.Add(textdb_encoding,
                         getMeta(textdb_encoding, SQL_PROPERTY,
                                                "ISO-8859-1"));
            textMeta.Add(textdb_cache_scale,
                         getMeta(textdb_cache_scale, SQL_PROPERTY,
                                                10, 8, 16));
            textMeta.Add(textdb_cache_size_scale,
                         getMeta(textdb_cache_size_scale,
                                                SQL_PROPERTY, 10, 6, 20));
            foreach (var pair in textMeta)
                dbMeta.Add(pair.Key, pair.Value);

            // string defaults for protected props
            dbMeta.Add(effiproz_version,
                       getMeta(effiproz_version, FILE_PROPERTY,
                                              null));
            dbMeta.Add(effiproz_modified,
                       getMeta(effiproz_modified, FILE_PROPERTY,
                                              null));

            // boolean defaults for protected props
            dbMeta.Add(effiproz_readonly,
                       getMeta(effiproz_readonly, FILE_PROPERTY,
                                              false));
            dbMeta.Add(effiproz_files_readonly,
                       getMeta(effiproz_files_readonly,
                                              FILE_PROPERTY, false));

            // integral defaults for protected props
            // this property is either 1 or 8 - only 8 for new databases
            dbMeta.Add(effiproz_cache_file_scale,
                       getMeta(effiproz_cache_file_scale,
                                              FILE_PROPERTY, 8, new byte[] {
            1, 8
        }));

            // string defaults for user defined props
            dbMeta.Add(effiproz_tx,
                       getMeta(effiproz_tx, SQL_PROPERTY, "MVCC"));
            dbMeta.Add(effiproz_temp_directory,
                       getMeta(effiproz_temp_directory, SQL_PROPERTY,
                                              null));
            dbMeta.Add(effiproz_default_table_type,
                       getMeta(effiproz_default_table_type,
                                              SQL_PROPERTY, "MEMORY"));

            // boolean defaults for user defined props
            dbMeta.Add(effiproz_inc_backup,
                       getMeta(effiproz_inc_backup, SQL_PROPERTY,
                                              true));
            dbMeta.Add(effiproz_lock_file,
                       getMeta(effiproz_lock_file, SQL_PROPERTY,
                                              true));
            dbMeta.Add(effiproz_nio_data_file,
                       getMeta(effiproz_nio_data_file, SQL_PROPERTY,
                                              true));

            // char padding to size and exception if data is too long
            dbMeta.Add(sql_enforce_size,
                       getMeta(sql_enforce_size, SQL_PROPERTY,
                                              true));
            dbMeta.Add(sql_enforce_strict_size,
                       getMeta(sql_enforce_strict_size,
                                              SQL_PROPERTY, true));

            // SQL reserved words not allowed as some identifiers
            dbMeta.Add(sql_enforce_names,
                       getMeta(sql_enforce_names, SQL_PROPERTY,
                                              false));
            dbMeta.Add(sql_compare_in_locale,
                       getMeta(sql_compare_in_locale, SQL_PROPERTY,
                                              false));
            dbMeta.Add(effiproz_write_delay,
                       getMeta(effiproz_write_delay, SQL_PROPERTY,
                                              true));

            // integral defaults for user-defined set props
            dbMeta.Add(effiproz_applog,
                       getMeta(effiproz_applog, SQL_PROPERTY, 0, 0,
                                              2));
            dbMeta.Add(effiproz_script_format,
                       getMeta(effiproz_script_format, SQL_PROPERTY,
                                              0, new byte[] {
            0, 1, 3
        }));

            // integral defaults for user defined range props
            dbMeta.Add(effiproz_log_size,
                       getMeta(effiproz_log_size, SQL_PROPERTY, 50,
                                              0, 1000));
            dbMeta.Add(effiproz_defrag_limit,
                       getMeta(effiproz_defrag_limit, SQL_PROPERTY,
                                              20, 0, 100));
            dbMeta.Add(runtime_gc_interval,
                       getMeta(runtime_gc_interval, SQL_PROPERTY,
                                              0, 0, 1000000));
            dbMeta.Add(effiproz_cache_size,
                       getMeta(effiproz_cache_size, SQL_PROPERTY,
                                              10000, 100, 1000000));
            dbMeta.Add(effiproz_cache_rows,
                       getMeta(effiproz_cache_rows, SQL_PROPERTY,
                                              50000, 100, 1000000));
            dbMeta.Add(effiproz_cache_free_count_scale,
                       getMeta(effiproz_cache_free_count_scale,
                                              SQL_PROPERTY, 9, 6, 12));
            dbMeta.Add(effiproz_result_max_memory_rows,
                       getMeta(effiproz_result_max_memory_rows,
                                              SQL_PROPERTY, 0, 0, 1000000));
            dbMeta.Add(effiproz_max_nio_scale,
                       getMeta(effiproz_max_nio_scale, SQL_PROPERTY,
                                              28, 24, 31));
        }

        /**
         * If the system property "hsqldb.method_class_names" is not set, then
         * static methods of all available Java classes can be accessed as functions
         * _in HSQLDB. If the property is set, then only the list of semicolon
         * seperated method names becomes accessible. An empty property value means
         * no class is accessible.<p>
         *
         * A property value that ends with .* is treated as a wild card and allows
         * access to all classe or method names formed by substitution of the
         * asterisk.<p>
         *
         * All methods of org.hsqldb.Library and java.lang.Math are always
         * accessible.
         *
         *
         */
        public static bool supportsJavaMethod(string name)
        {

            if (accessibleCSharpMethodNames == null)
            {
                return true;
            }

            if (name.StartsWith("org.hsqldb.Library."))
            {
                return true;
            }

            if (name.StartsWith("java.lang.Math."))
            {
                return true;
            }

            if (accessibleCSharpMethodNames.contains(name))
            {
                return true;
            }

            Iterator it = accessibleCSharpMethodNames.iterator();
            while (it.hasNext())
            {
                string className = (string)it.next();
                int limit = className.LastIndexOf(".*");

                if (limit < 1)
                {
                    continue;
                }

                if (name.StartsWith(className.Substring(0, limit + 1 - (0))))
                {
                    return true;
                }
            }

            return false;
        }


        // accessibility
        public const int SYSTEM_PROPERTY = 0;
        public const int SQL_PROPERTY = 2;
        public const int FILE_PROPERTY = 1;

        // db files modified
        public const int FILES_NOT_MODIFIED = 0;
        public const int FILES_MODIFIED = 1;
        public const int FILES_NEW = 2;
        private const string MODIFIED_NO = "no";
        private const string MODIFIED_YES = "yes";
        private const string MODIFIED_NEW = "no-new-files";

        // allowed property metadata
        private static Dictionary<string, object[]> dbMeta = new Dictionary<string, object[]>(StringComparer.InvariantCultureIgnoreCase);
        private static Dictionary<string, object[]> textMeta = new Dictionary<string, object[]>(StringComparer.InvariantCultureIgnoreCase);

        // versions
        public const string VERSION_STRING_1_8_0 = "1.8.0";
        public const string VERSION_STRING_0_1_0 = "0.1.0";
        public const string THIS_VERSION = "0.1.0";
        public const string THIS_FULL_VERSION = "0.1.0.1";
        public const string THIS_CACHE_VERSION = "1.9.0";
        public const string PRODUCT_NAME = "EffiProz Database Engine";
        public const int MAJOR = 1, MINOR = 9, REVISION = 0;

        /**
         * system properties supported by HSQLDB
         */
        public const string system_lockfile_poll_retries_property =
            "effiproz.lockfile_poll_retries";
        public const string system_max_char_or_varchar_display_size =
            "effiproz.max_char_or_varchar_display_size";

        //
        public const String effiproz_inc_backup = "effiproz.incremental_backup";

        //
        public const String effiproz_version = "version";
        public const String effiproz_readonly = "readonly";
        private const String effiproz_modified = "modified";


        //
        public const String runtime_gc_interval = "runtime.gc_interval";

        //
        public const String url_ifexists = "ifexists";
        public const String url_default_schema = "default_schema";


        //
        public const String effiproz_tx = "effiproz.tx";
        public const string effiproz_applog = "effiproz.applog";
        public const string effiproz_cache_file_scale =
            "effiproz.cache_file_scale";
        public const string effiproz_cache_free_count_scale =
            "effiproz.cache_free_count_scale";
        public const String effiproz_cache_rows = "effiproz.cache_rows";
        public const String effiproz_cache_size = "effiproz.cache_size";
        public const string effiproz_default_table_type =
            "effiproz.default_table_type";
        public const string effiproz_defrag_limit = "effiproz.defrag_limit";
        public const string effiproz_files_readonly =
            "effiproz.files_readonly";
        public const string effiproz_lock_file = "effiproz.lock_file";
        public const string effiproz_log_size = "effiproz.log_size";
        public const string effiproz_nio_data_file = "effiproz.nio_data_file";
        public const string effiproz_max_nio_scale = "effiproz.max_nio_scale";
        public const string effiproz_raf_buffer_scale =
            "effiproz.raf_buffer_scale";
        private const string effiproz_original_version =
            "effiproz.original_version";
        public const string effiproz_script_format = "effiproz.script_format";
        public const String effiproz_temp_directory = "effiproz.temp_directory";
        public const String effiproz_result_max_memory_rows =
        "effiproz.result_max_memory_rows";
        public const String effiproz_write_delay = "effiproz.write_delay";

        //
        public const string sql_compare_in_locale =
            "sql.compare_in_locale";
        public const String sql_enforce_size = "sql.enforce_size";
        public const string sql_enforce_strict_size =
            "sql.enforce_strict_size";
        public const string sql_tx_no_multi_write =
            "sql.tx_no_multi_rewrite";
        public const String sql_enforce_names = "sql.enforce_names";

        //
        public const string textdb_cache_scale = "textdb.cache_scale";
        public const string textdb_cache_size_scale =
            "textdb.cache_size_scale";
        public const string textdb_all_quoted = "textdb.all_quoted";
        public const string textdb_allow_full_path =
            "textdb.allow_full_path";
        public const string textdb_encoding = "textdb.encoding";
        public const string textdb_ignore_first = "textdb.ignore_first";
        public const string textdb_quoted = "textdb.quoted";
        public const string textdb_fs = "textdb.fs";
        public const string textdb_vs = "textdb.vs";
        public const string textdb_lvs = "textdb.lvs";

        //
        public const String url_storage_class_name = "storage_class_name";
        public const String url_fileaccess_class_name =
            "fileaccess_class_name";
        public const String url_storage_key = "storage_key";
        public const String url_shutdown = "shutdown";
        //
        public const String url_crypt_key = "crypt_key";
        public const String url_crypt_type = "crypt_type";
        public const String url_crypt_iv = "crypt_iv";


        private Database database;

        public EffiProzDatabaseProperties(Database db)
            : base(db.getPath(), db.logger.getFileAccess())
        {

            database = db;
            setNewDatabaseProperties();

        }

        void setNewDatabaseProperties()
        {

            // version of a new database
            setProperty(effiproz_version, THIS_VERSION);
            setProperty(effiproz_modified, "no-new-files");

            // OOo related code
            if (database.logger._isStoredFileAccess)
            {
                setProperty(effiproz_cache_rows, 25000);
                setProperty(effiproz_cache_size, 6000);
                setProperty(effiproz_log_size, 10);
                setProperty(sql_enforce_size, true);
                setProperty(effiproz_nio_data_file, false);
            }

            // OOo end

            setProperty(url_shutdown, true);
        }

        /**
         * Creates file with defaults if it didn't exist.
         * Returns false if file already existed.
         */
        public override bool load()
        {

            bool exists;

            if (!DatabaseURL.isFileBasedDatabaseType(database.getType()))
            {
                return true;
            }

            try
            {
                exists = base.load();
            }
            catch (Exception t)
            {
                throw Error.error(t, ErrorCode.FILE_IO_ERROR,
                                       ErrorCode.M_LOAD_SAVE_PROPERTIES, new Object[] {
                t.Message, fileName
            });
            }

            if (!exists)
            {
                return false;
            }

            filterLoadedProperties();

            string version = getProperty(effiproz_version);


            int check = version.Substring(0, 5).CompareTo(THIS_VERSION);

            // do not open if the database belongs to a later (future) version
            if (check > 0)
            {
                throw Error.error(ErrorCode.WRONG_DATABASE_FILE_VERSION);
            }

            // do not open modified databases of compatible earlier versions
            if (check < 0)
            {
                if (!MODIFIED_NO.Equals(getStringProperty(effiproz_modified)))
                {
                    throw Error.error(ErrorCode.SHUTDOWN_REQUIRED);
                }
            }

            if (getIntegerProperty(effiproz_script_format) != 0)
            {
                throw Error.error(ErrorCode.WRONG_DATABASE_FILE_VERSION);
            }


            return true;
        }


        public override void save()
        {

            if (!DatabaseURL.isFileBasedDatabaseType(database.getType())
                    || database.isFilesReadOnly())
            {
                return;
            }

            try
            {
                EffiProzProperties props = new EffiProzProperties(
                database.getPath(), database.logger.getFileAccess());

                props.setProperty(effiproz_version, THIS_VERSION);
                props.setProperty(effiproz_modified, getProperty(effiproz_modified));

                props.save(fileName + ".properties" + ".new");
                fa.RenameElement(fileName + ".properties" + ".new",
                                 fileName + ".properties");
            }
            catch (Exception t)
            {
                database.logger.logSevereEvent("save failed", t);

                throw Error.error(t, ErrorCode.FILE_IO_ERROR,
                                  ErrorCode.M_LOAD_SAVE_PROPERTIES, new Object[] {
                t.Message, fileName
            });
            }
        }

        void filterLoadedProperties()
        {

            var en = stringProps.Keys;

            List<string> removeList = new List<string>();

            foreach (var key in en)
            {

                bool accept = dbMeta.ContainsKey(key);

                if (!accept)
                {
                    removeList.Add(key);

                }
            }

            foreach (var key in removeList)
            {
                stringProps.Remove(key);
            }

        }

        /**
         *  overload file database properties with any passed on URL line
         *  do not store password etc
         */
        public void setURLProperties(EffiProzProperties p)
        {

            if (p != null)
            {
                foreach (var propertyName in p.propertyNames())
                {
                    Object[] row;

                    if (dbMeta.TryGetValue(propertyName, out row))
                    {

                        if (row != null
                                    || ((int)row[indexType])
                                       == SQL_PROPERTY)
                        {

                            // can add error checking with defaults
                            setProperty(propertyName, p.getProperty(propertyName));
                        }
                    }
                }
            }
        }

        public HashSet getUserDefinedPropertyData()
        {
            HashSet set = new HashSet();

            foreach (var row in dbMeta.Values)
            {
                if (((int)row[indexType]) == SQL_PROPERTY)
                {
                    set.add(row);
                }
            }

            return set;
        }

        public bool isUserDefinedProperty(string key)
        {

            Object[] row = (Object[])dbMeta[key];

            return row != null
                   && ((int)row[indexType]) == SQL_PROPERTY;
        }

        public bool isBoolean(string key)
        {

            Object[] row = (Object[])dbMeta[key];

            return row != null && row[indexClass].Equals("bool")
                   && ((int)row[indexType]) == SQL_PROPERTY;
        }

        public bool isIntegral(string key)
        {

            Object[] row = (Object[])dbMeta[key];

            return row != null && row[indexClass].Equals("int")
                   && ((int)row[indexType]) == SQL_PROPERTY;
        }

        public bool isString(string key)
        {

            Object[] row = (Object[])dbMeta[key];

            return row != null && row[indexClass].Equals("string")
                   && ((int)row[indexType]) == SQL_PROPERTY;
        }

        public string setDatabaseProperty(string key,
                                          string value)
        {

            Object[] row = (Object[])dbMeta[key];

            // can check bounds here
            value = base.setProperty(key, value);

            return value;
        }

        public int getDefaultWriteDelay()
        {

            // OOo related code
            if (database.logger.isStoredFileAccess())
            {
                return 2000;
            }

            // OOo end
            return 10000;
        }

        public void setDBModified(int mode)
        {

            string value = MODIFIED_NO;

            if (mode == FILES_MODIFIED)
            {
                value = MODIFIED_YES;
            }
            else if (mode == FILES_NEW)
            {
                value = MODIFIED_NEW;
            }

            setProperty(effiproz_modified, value);
            save();
        }

        public int getDBModified()
        {

            string value = getProperty("modified");

            if (MODIFIED_YES.Equals(value))
            {
                return FILES_MODIFIED;
            }
            else if (MODIFIED_NEW.Equals(value))
            {
                return FILES_NEW;
            }

            return FILES_NOT_MODIFIED;
        }

        // column number mappings
        public const int indexName = 0;
        public const int indexType = 1;
        public const int indexClass = 2;
        public const int indexIsRange = 3;
        public const int indexDefaultValue = 4;
        public const int indexRangeLow = 5;
        public const int indexRangeHigh = 6;
        public const int indexValues = 7;
        public const int indexLimit = 9;

        private static Object[] getMeta(string name, int accessLevel,
                                        string defaultValue)
        {

            Object[] row = new Object[indexLimit];

            row[indexName] = name;
            row[indexType] = (accessLevel);
            row[indexClass] = "string";
            row[indexDefaultValue] = defaultValue;

            return row;
        }

        private static Object[] getMeta(string name, int accessLevel,
                                        bool defaultValue)
        {

            Object[] row = new Object[indexLimit];

            row[indexName] = name;
            row[indexType] = (accessLevel);
            row[indexClass] = "bool";
            row[indexDefaultValue] = defaultValue ? true
                                                  : false;

            return row;
        }

        private static Object[] getMeta(string name, int accessLevel,
                                        int defaultValue, byte[] values)
        {

            Object[] row = new Object[indexLimit];

            row[indexName] = name;
            row[indexType] = (accessLevel);
            row[indexClass] = "int";
            row[indexDefaultValue] = (defaultValue);
            row[indexValues] = values;

            return row;
        }

        private static Object[] getMeta(string name, int accessLevel,
                                        int defaultValue, int rangeLow,
                                        int rangeHigh)
        {

            Object[] row = new Object[indexLimit];

            row[indexName] = name;
            row[indexType] = (accessLevel);
            row[indexClass] = "int";
            row[indexDefaultValue] = (defaultValue);
            row[indexIsRange] = true;
            row[indexRangeLow] = (rangeLow);
            row[indexRangeHigh] = (rangeHigh);

            return row;
        }

        public override bool isPropertyTrue(String key)
        {

            Boolean value;
            Object[] metaData;

            if (!dbMeta.TryGetValue(key, out metaData))
            {
                throw Error.error(ErrorCode.X_42511);
            }
            value = (Boolean)metaData[indexDefaultValue];

            String prop = stringProps.GetProperty(key);
            bool isSystem =
                ((int)metaData[indexType])
                == SYSTEM_PROPERTY;

#if !SILVERLIGHT && !PLATFORM_COMPACTFRAMEWORK
            if (prop == null && isSystem)
            {
                prop = MediumTrustHelper.RunningMediumTrust ? null : Environment.GetEnvironmentVariable(key);
            }
#endif

            if (prop != null)
            {
                value = bool.Parse(prop);
            }

            return value;
        }

        public String getStringProperty(String key)
        {

            String value;
            Object[] metaData;

            if (!dbMeta.TryGetValue(key, out metaData))
            {
                throw Error.error(ErrorCode.X_42511);
            }

            value = (String)metaData[indexDefaultValue];

            String prop = stringProps.GetProperty(key);

            if (prop != null)
            {
                value = prop;
            }

            return value;
        }

        public int getIntegerProperty(String key)
        {

            int value;
            Object[] metaData;

            if (!dbMeta.TryGetValue(key, out metaData))
            {
                throw Error.error(ErrorCode.X_42511);
            }

            value =
                ((int)metaData[indexDefaultValue]);

            String prop = stringProps.GetProperty(key);

            if (prop != null)
            {
                try
                {
                    value = int.Parse(prop);
                }
                catch (FormatException) { }
            }
            return value;
        }

        public static IEnumerable<object[]> getPropertiesMetaIterator()
        {
            return dbMeta.Values;
        }

        public const int NO_MESSAGE = 1;

        public int getErrorLevel()
        {

            //      return 0;
            return NO_MESSAGE;
        }
    }
}
